home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Practical Algorithms for Image Analysis
/
Practical Algorithms for Image Analysis.iso
/
CH_6.1
/
SPP
/
SPP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-11
|
6KB
|
279 lines
/*
* spp.c
*
* Practical Algorithms for Image Analysis
*
* Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
*/
/*
* S(can) P(oint) P(attern)
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "spp.h"
#undef DEBUG
#undef SHOW_PP
#undef DEBUG_SORT
#define ON 1
#define OFF 0
/* globals */
unsigned char **image; /* input/output image */
int NMAX = 4000; /* max no point objects in image */
int offset_of_y = OFFSETOF (struct Pix, y);
int offset_of_x = OFFSETOF (struct Pix, x);
extern char *optarg;
extern int optind, opterr;
int POINT_OBJ = ON; /* default: assume pattern of point-objs */
int SORT = OFF;
int WRITE_FILE = OFF;
/*
* comparison function for qsort():
* sort array of tuples in order of increassing y-values (not tested)
*/
int
compare (t1, t2)
const void *t1, *t2;
{
int i1, i2;
i1 = *(int *) ((struct Pix *) t1 + offset_of_y);
i2 = *(int *) ((struct Pix *) t2 + offset_of_y);
return ((int) SIGN (i1 - i2));
}
void
fail_alloc (char *str, int code)
{
printf ("\n...memory alloc for %s failed\n", str);
exit (code);
}
/*
* usage of routine
*/
void
usage (char *progname)
{
progname = last_bs (progname);
printf ("USAGE: %s inimg [-d] [-w file] [-L]\n", progname);
printf ("\n%s scans a point pattern in a given image\n", progname);
printf ("and generates data for later Vornoi analysis.\n\n");
printf ("ARGUMENTS:\n");
printf (" inimg: input image filename (TIF)\n\n");
printf ("OPTIONS:\n");
printf (" -d : default mode: scan pattern of point-like objects\n");
printf (" marked in max_index-1 (254);\n");
printf (" data are generated in order of increasing y-coordinates.\n");
printf (" -w file: write file (.vin) to disk\n");
printf (" -L : print Software License for this module\n");
exit (1);
}
void
main (int argc, char *argv[])
{
int i;
int nrows, ncols;
struct Pix *Cxy;
long n_pts;
int status;
int xmin, ymin, xmax, ymax;
int jmin, imin, jmax, imax;
int left_x, right_x;
char *buf;
int i_arg;
FILE *file;
Image *imgIO; /* structure for I/O images */
char in_filename[256];
/*
* cmd line options
*/
static char *optstring = "dw:L";
in_filename[0] = '\0';
/*
* parse command line
*/
optind = 2;
opterr = ON; /* give error messages */
if (argc < 2)
usage (argv[0]);
while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
printf ("\n");
switch (i_arg) {
case 'd':
printf ("...option %c: default mode\n", i_arg);
POINT_OBJ = ON;
break;
case 'w':
printf ("...option %c: write file %s to disk\n",
i_arg, buf = optarg);
if ((file = fopen (buf, "w")) == NULL) {
puts ("\n...could not open output file");
exit (1);
}
WRITE_FILE = ON;
break;
case 'L':
print_sos_lic ();
exit (0);
default:
printf ("...unknown condition encountered\n");
exit (1);
break;
}
}
strcpy (in_filename, argv[1]);
/*
* get the image
*/
imgIO = ImageIn (in_filename);
if (imgIO->bps == 8 && imgIO->spp == 3) {
printf ("Got RGB image!!!\n");
fprintf (stderr, "Can only work with Grayscale or Binary TIFF files!!!\n");
exit (1);
}
image = imgIO->img;
nrows = imgIO->height;
ncols = imgIO->width;
jmin = imin = 0;
jmax = ncols;
imax = nrows;
left_x = jmin;
right_x = jmax - 1;
ncols = jmax - jmin;
nrows = imax - imin;
#ifdef DEBUG
printf ("\n...ncols = %d, nrows = %d\n", ncols, nrows);
#endif
/*
* zero outer border of image
*/
zero_border (imgIO, 1);
/*
* memory allocation
*/
if ((Cxy = (struct Pix *) calloc (NMAX, sizeof (struct Pix))) == NULL)
fail_alloc ("Cxy", 1);
/*
* extract coordinates of objects in point pattern
* -->note: data are extracted in order of increasing y!!
*/
printf ("\n...extracting point object coordinates:");
n_pts = 0;
if ((status = x_pp (Cxy, &n_pts, left_x, imin, right_x, imax)) == 0) {
printf ("\n...no objects exceeds NMAX = %d\n", NMAX);
exit (1);
}
else
printf ("\n...found %ld points\n", n_pts);
/* realloc */
#ifdef SHOW_PP
printf ("\n...point coordinates:\n");
for (i = 0; i < n_pts; i++) {
printf ("... x[%d] = %4d, y[%d] = %4d\n",
i, (Cxy + i)->x, i, (Cxy + i)->y);
}
#endif
if (SORT == OFF) {
printf ("\n...find extrema in (unsorted) data...\n");
xmin = xmax = (Cxy + 0)->x;
ymin = ymax = (Cxy + 0)->y;
for (i = 1; i < n_pts; i++) {
if ((Cxy + i)->x < xmin)
xmin = (Cxy + i)->x;
if ((Cxy + i)->x > xmax)
xmax = (Cxy + i)->x;
if ((Cxy + i)->y < ymin)
ymin = (Cxy + i)->y;
if ((Cxy + i)->y > ymax)
ymax = (Cxy + i)->y;
}
printf ("\n...xmin = %4d, ymin = %4d\n", xmin, ymin);
printf ("\n...xmax = %4d, ymax = %4d\n", xmax, ymax);
}
/*
* sort Cxy if required for later use
*/
else if (SORT == ON) {
printf ("\n...sort data and find extrema...\n");
qsort (Cxy, n_pts, sizeof (struct Pix), compare);
xmin = xmax = (Cxy + 0)->x;
for (i = 1; i < n_pts; i++) {
if ((Cxy + i)->x < xmin)
xmin = (Cxy + i)->x;
if ((Cxy + i)->x > xmax)
xmax = (Cxy + i)->x;
}
ymin = (Cxy + 0)->y;
ymax = (Cxy + n_pts - 1)->y;
#ifdef DEBUG_SORT
printf ("\n...data after sorting:\n");
for (i = 0; i < n_pts; i++) {
printf ("... x[%d] = %4d, y[%d] = %4d\n",
i, (Cxy + i)->x, i, (Cxy + i)->y);
}
printf ("\n...xmin = %4d, ymin = %4d\n", xmin, ymin);
printf ("\n...xmax = %4d, ymax = %4d\n", xmax, ymax);
#endif
}
/*
* write data file of format ( .vin) for use by Voronoi routines
*/
if (WRITE_FILE == ON) {
write_vin_file (file, (int) n_pts, xmin, ymin, xmax, ymax, Cxy);
fclose (file);
}
if (POINT_OBJ == ON)
free (Cxy);
}